<template>
  <div class="motionBox p-4" @mousemove="handleMouseMove">
    <motion.div class="ball absolute left-0 top-0 z-100 pointer-events-none" :animate="mouseFollowStyle"
      :transition="mouseFollowTransition as any" />

    <div class="flex justify-center items-center gap-4">
      <motion.div :initial="initial" :animate="animate" :transition="transition as any"
        class="w-[100px] h-[100px] mt-10 border border-[4px] border-[#146EDD] rounded-[10px]">
      </motion.div>
      <motion.div :initial="initial" :animate="animate2" :transition="transition as any"
        class="w-[100px] h-[100px] mt-10 border border-[4px] border-[#146EDD] rounded-[10px]">
      </motion.div>
    </div>
    <!-- 关键帧动画 -->
    <motion.div :animate="{
      scale: [1, 2, 2, 1, 1],
      rotate: [0, 0, 180, 180, 0],
      borderRadius: ['0%', '0%', '50%', '50%', '0%']
    }" :transition="{
      duration: 1,
      ease: 'easeInOut',
      times: [0, 0.2, 0.5, 0.8, 1],
      repeat: 0,
      repeatType: 'loop',
      repeatDelay: 1
    }" class="box" />

    <motion.div :initial="{ scale: 1 }" :whileHover="{ scale: 1.2 }" :whilePress="{ scale: 0.8 }"
      @hoverStart="() => console.log('hover started!')" class="box mt-10" />
    <motion.div :initial="{ opacity: 0, scale: 0 }" :animate="{ opacity: 1, scale: 1 }" :transition="{
      duration: 0.4,
      scale: { type: 'spring', visualDuration: 0.4, bounce: 0.5 }
    }" class="ball mt-4" />

    <div class="mt-4">
      <motion.svg width="600" height="200" viewBox="0 0 600 200" initial="hidden" animate="visible" :style="image">
        <motion.circle cx="100" cy="100" r="80" stroke="#ff0088" :variants="draw as any" :custom="1" :style="shape" />
        <motion.line x1="220" y1="30" x2="360" y2="170" stroke="#4ff0b7" :variants="draw as any" :custom="2"
          :style="shape" />
        <motion.line x1="220" y1="170" x2="360" y2="30" stroke="#4ff0b7" :variants="draw as any" :custom="2.5"
          :style="shape" />
        <motion.rect width="140" height="140" x="410" y="30" rx="20" stroke="#0d63f8" :variants="draw as any"
          :custom="3" :style="shape" />
      </motion.svg>
    </div>

    <div class="container">
      <AnimatePresence :initial="false">
        <motion.div v-if="isVisible" :initial="{ opacity: 0, scale: 0 }" :animate="{ opacity: 1, scale: 1 }"
          :exit="{ opacity: 0, scale: 0 }" class="box" key="box" />
      </AnimatePresence>
      <motion.button class="button" @click="isVisible = !isVisible" :whilePress="{ y: 10 }">
        {{ isVisible ? 'Hide' : 'Show' }}
      </motion.button>
    </div>
    <div class="h-[400px] w-[1000px] my-10">
      <motion.div ref="constraintsRef" class="w-[1000px] h-[200px] bg-[#f003]">
        <motion.div class="box flex items-center justify-center" drag :dragConstraints="constraintsRef">
          drag
        </motion.div>
      </motion.div>
      <motion.div class="box flex items-center justify-center" drag="x" :dragConstraints="{ left: 0, right: 1000 }">
        drag x
      </motion.div>
    </div>

    <div class="mt-[100px]">
      <el-radio-group v-model="tabPosition">
        <el-radio-button value="top">top</el-radio-button>
        <el-radio-button value="right">right</el-radio-button>
        <el-radio-button value="bottom">bottom</el-radio-button>
        <el-radio-button value="left">left</el-radio-button>
      </el-radio-group>

      <el-tabs :tab-position="tabPosition" class="demo-tabs mt-10">
        <el-tab-pane label="User">
          <motion.div :initial="init" :whileInView="whileIn" :transition="transi as any">
            User
          </motion.div>
        </el-tab-pane>
        <el-tab-pane label="Config">
          <motion.div :initial="init" :whileInView="whileIn" :transition="transi as any">
            Config
          </motion.div>
        </el-tab-pane>
        <el-tab-pane label="Role">
          <motion.div :initial="init" :whileInView="whileIn" :transition="transi as any">
            Role
          </motion.div>
        </el-tab-pane>
        <el-tab-pane label="Task">
          <motion.div :initial="init" :whileInView="whileIn" :transition="transi as any">
            Task
          </motion.div>
        </el-tab-pane>
      </el-tabs>
    </div>

    <div class="mt-[100px]">
      <el-empty class="emptyBox" :image-size="200" />
      <el-empty class="emptyBox" :image-size="200" />
      <el-empty class="emptyBox" :image-size="200" />
      <el-empty class="emptyBox" :image-size="200" />
    </div>

    <motion.div :initial="{ x: 0, y: 200, opacity: 0 }" :whileInView="{ x: 0, y: 0, opacity: 1 }" :transition="{
      delay: 0.1, duration: 0.3, ease: 'easeInOut',
    }">
      <el-empty :image-size="200" />
    </motion.div>

    <motion.div :initial="{ opacity: 0 }" :whileInView="{ opacity: 1 }" :transition="{
      delay: 0.3, duration: 0.8, ease: 'easeInOut',
    }" class="ball mt-[1000px]"></motion.div>
    <motion.div :initial="{ opacity: 0, y: 40, filter: 'blur(10px)' }" :whileInView="{
      opacity: 1, y: 0, filter: 'blur(0px)',
    }" :transition="{
      delay: 0.3, duration: 0.8, ease: 'easeInOut',
    }" class="mt-10">
      <div>出淤泥而不染，濯清涟而不妖</div>
    </motion.div>
    <motion.div :initial="{ opacity: 0, y: 40, filter: 'blur(10px)' }" :whileInView="{
      opacity: 1, y: 0, filter: 'blur(0px)',
    }" :transition="{
      delay: 0.5, duration: 0.8, ease: 'easeInOut',
    }" class="mt-4">
      <div>无丝竹之乱耳，无案牍之劳形</div>
    </motion.div>
    <motion.div :initial="{ opacity: 0, y: 40, filter: 'blur(10px)' }" :whileInView="{
      opacity: 1, y: 0, filter: 'blur(0px)',
    }" :transition="{
      delay: 0.7, duration: 0.8, ease: 'easeInOut',
    }" class="mt-4">
      <div>十步杀一人，千里不留行</div>
      <div>事了拂衣去，深藏身与名</div>
      <div class="text-[24px] leading-[2] font-bold text-justify">
        <FormattedNumber value="123456.6655" />
      </div>
    </motion.div>
    <motion.div :initial="{ y: 100, opacity: 0 }" :whileInView="{ y: 0, opacity: 1 }" :transition="{
      delay: 0.1, duration: 0.3, ease: 'easeInOut'
    }">
      <div class="slogan w-[800px] mx-auto text-[36px] font-bold text-center border border-[0px] mt-[100px] mb-[100px]">
        这是一个文字颜色渐变运动的动画
      </div>
    </motion.div>
    <motion.div :style="{ scaleX: scrollYProgress }"
      class="fixed left-0 bottom-0 w-full h-[10px] bg-[#146EDD] origin-left" />
    <footer></footer>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { motion, useScroll, AnimatePresence, useDomRef } from 'motion-v'
import FormattedNumber from '@/components/FormattedNumber/index.vue'
const { scrollYProgress } = useScroll()
const constraintsRef = useDomRef()
const isVisible = ref(true)
import type { TabsInstance } from 'element-plus'
const tabPosition = ref<TabsInstance['tabPosition']>('left')

// 添加鼠标位置跟踪
const mouseX = ref(0)
const mouseY = ref(0)

// 计算鼠标跟随样式
const mouseFollowStyle = ref({
  x: 0,
  y: 0,
  opacity: 1,
  scale: 1
})

// 鼠标跟随的过渡配置
const mouseFollowTransition = {
  delay: 0,// 延迟，单位秒
  type: 'spring',// 弹簧动画
  bounce: 0.5,// 弹跳，值越大，弹跳越敏感，设置以下会被覆盖：stiffness damping mass
  // damping: 10,// 阻尼，值越大，动画越不敏感
  // stiffness: 100,// 刚度，值越大，动画越敏感
  // mass: 1,// 质量，值越大，动画越敏感
  // velocity: 2,// 速度，值越大，动画越快
  ease: 'easeInOut',// 动画曲线，easeInOut 表示先加速后减速
  duration: 0.3,// 动画时长，单位秒，设置以下会被覆盖：visualDuration
  // visualDuration: 5,// 可视化动画时长，单位秒
  repeat: 0,// 重复次数，设置为 Infinity 表示无限重复
  repeatType: 'reverse',// 重复类型，reverse 表示反向重复，loop 表示重头开始
  repeatDelay: 0,// 重复延迟，单位秒
}

// 处理鼠标移动事件
const handleMouseMove = (e: MouseEvent) => {
  const { left, top } = (e.currentTarget as HTMLElement).getBoundingClientRect()
  mouseX.value = e.clientX - left
  mouseY.value = e.clientY - top

  // 更新跟随元素的位置，使鼠标位于元素中心
  mouseFollowStyle.value = {
    x: mouseX.value - 50, // 元素宽度的一半 (100px/2 = 50px)
    y: mouseY.value - 50, // 元素高度的一半 (100px/2 = 50px)
    opacity: 1,
    scale: 1,
  }
}
const initial = { rotate: 0 }
const animate = { rotate: -360 }
const animate2 = { rotate: 360 }
const transition = {
  type: 'tween',
  delay: 0.3,
  duration: 10,
  ease: 'linear',
  repeat: Infinity,
  repeatType: 'loop'
}
const init = { y: 100, opacity: 0 }
const whileIn = { y: 0, opacity: 1 }
const transi = {
  type: 'tween',
  delay: 0.1,
  duration: 0.3,
  ease: 'easeInOut',
}

const draw = {
  hidden: { pathLength: 0, opacity: 0 },
  visible: (i: number) => {
    const delay = i * 0.5
    return {
      pathLength: 1,
      opacity: 1,
      transition: {
        pathLength: { delay, type: "spring", duration: 1, bounce: 0 },
        opacity: { delay, duration: 0.01 },
      },
    }
  },
}

const image = {
  maxWidth: "80vw",
  background: "#f003"
}

const shape = {
  strokeWidth: 10,
  strokeLinecap: "round",
  fill: "transparent",
}
</script>
<style scoped lang="scss">
.motionBox {
  position: relative;
}

@keyframes masked-animation {
  0% {
    background-position: 0 0
  }

  to {
    background-position: -100% 0
  }
}

.slogan {
  background: linear-gradient(270deg, #ff7669 0, hsla(5, 79%, 81%, .95) 5%, hsla(0, 0%, 100%, .95) 10%, hsla(0, 0%, 100%, .95) 90%, hsla(5, 79%, 81%, .95) 95%, #ff7669);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-size: 200% 100%;
  animation: masked-animation 5s linear infinite;
}

.ball {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: #8df0cc;
}

.box {
  width: 100px;
  height: 100px;
  border-radius: 10px;
  background-color: #0d63f8;
}

.container {
  display: flex;
  flex-direction: column;
  width: 100px;
  height: 160px;
  position: relative;

  .box {
    margin-top: 10px;
    border-radius: 50%;
  }

  .button {
    background-color: #0cdcf7;
    border-radius: 10px;
    padding: 10px 20px;
    color: #0f1115;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    cursor: pointer;
  }
}

.emptyBox {
  animation-name: slideIn;
  animation-timeline: view(); // 看到元素时候动画开始执行
  animation-range: 0% 100%; // 看到元素时候滚动到50%时候动画完成
}

footer {
  height: 10px;
  width: 100%;
  background: rgba(254, 178, 16, 1);
  position: fixed;
  left: 0;
  bottom: 10px;
  // animation: progress-expand 2s linear infinite alternate;
  animation: progress-expand linear;
  // 将动画时间线设置为与页面滚动关联
  animation-timeline: scroll();
  transform-origin: left;
}

@keyframes progress-expand {
  0% {
    // width: 0%;
    transform: scaleX(0);
  }

  100% {
    // width: 100%;
    transform: scaleX(1);
  }
}

@keyframes slideIn {
  0% {
    transform: translate(0%, 50%);
    opacity: 0;
  }

  100% {
    transform: translate(0%, 0%);
    opacity: 1;
  }
}

.demo-tabs>.el-tabs__content {
  padding: 32px;
  color: #6b778c;
  font-size: 32px;
  font-weight: 600;
}

.el-tabs--right .el-tabs__content,
.el-tabs--left .el-tabs__content {
  height: 100%;
}
</style>
